<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use DB;
use App\Support\MemcacheSASL;

class BaseModel extends Model
{

    public $error;

    public function __construct()
    {
        parent::__construct();
        // $this->memcache = new MemcacheSASL;
        // $this->memcache->addServer(env('MEMCACHE_HOST', '127.0.0.1'), env('MEMCACHE_PORT', '11211'));
    }

    /**
     * 删除指定MC
     */
    public function delMc($key)
    {
        if (is_array($key)) {
            foreach ($key as $v) {
                $this->memcache->delete($v);
            }
        } else {
            $this->memcache->delete($key);
        }
    }

    public function getError()
    {
        return $this->error;
    }

    /**
     * 仓储或model 使用return $query->multiWhere($map)->orderBy('task_id', 'DESC')->paginate($numPerPage);
     * 调用方式$map['category_pid'] = ['=', $type];
     * $tasklist = $this->task->getPaginateTaskList($map, 15);
     * 多条件查询where
     *
     * @return mixed
     * 2015-9-21 添加
     */
    public function scopeMultiWhere($query, $arr = '')
    {
        if (!is_array($arr)) {
            return $query;
        }
        if (empty($arr)) {
            return $query;
        }
        foreach ($arr as $key => $value) {
            //判断$arr
            if (is_array($value)) {
                $value[0] = strtolower($value[0]);
                switch ($value[0]) {
                    case 'like';
                        $query = $query->where($key, $value[0], $value[1]);
                        break;
                    case 'in':
                        $query = $query->whereIn($key, $value[1]);
                        break;
                    case 'between':
                        $query = $query->whereBetween($key, [$value[1][0], $value[1][1]]);
                        break;
                    case 'glt'://大于小于等于比较查询   $where['money'] = ['glt',[['>',1],['<=',2]]];
                        $query = $query->where($key, $value[1][0][0], $value[1][0][1])->where($key, $value[1][1][0], $value[1][1][1]);
                        break;
                    default:
                        $query = $query->where($key, $value[0], $value[1]);
                        break;
                }
            } else {
                $query = $query->where($key, $value);
            }
        }
        return $query;
    }

    public function scopeMultiJoin($query, $arr = '')
    {
        if (!is_array($arr)) {
            return $query;
        }
        if (empty($arr)) {
            return $query;
        }
        foreach ($arr as $key => $value) {
            //判断$arr
            if (is_array($value)) {
                $value[0] = strtolower($value[0]);
                $query = $query->join($key, $value[0], '=', $value[1]);
                if ($value[0] == 'left') {
                    $query = $query->leftJoin($key, $value[0], '=', $value[1]);
                }
            }
        }
        return $query;
    }


    public function scopeMultiHaving($query, $arr = '')
    {
        if (!is_array($arr)) {
            return $query;
        }
        if (empty($arr)) {
            return $query;
        }
        foreach ($arr as $key => $value) {
            //判断$arr
            if (is_array($value)) {
                $value[0] = strtolower($value[0]);
                if ($value[0]) {
                    $query = $query->having($key, $value[0], $value[1]);
                }
            } else {
                $query = $query->having($key, '=', $value);
            }
        }
        return $query;
    }

    /**
     * 仓储或model 使用return $query->multiOrder($order)->paginate($numPerPage);
     * 调用方式$order['created_at'] = 'desc';
     * $tasklist = $this->task->getPaginateTaskList($map, 15);
     * 多条件排序order
     *
     * @return mixed
     * 2016-3-7 添加
     */
    public function scopeMultiOrder($query, $arr = '')
    {
        if (!is_array($arr)) {
            return $query;
        }
        if (empty($arr)) {
            return $query;
        }
        foreach ($arr as $key => $value) {
            $query = $query->orderBy($key, $value);
        }
        return $query;
    }

    /**
     * 仓储或model 使用return $query->multiOrder($order)->paginate($numPerPage);
     * 调用方式$order['created_at'] = 'desc';
     * $tasklist = $this->task->getPaginateTaskList($map, 15);
     * 多条件排序order
     *
     * @return mixed
     * 2016-3-7 添加
     */
    public function scopeMultiGroup($query, $arr = '')
    {
        if (!is_array($arr)) {
            return $query;
        }
        if (empty($arr)) {
            return $query;
        }
        foreach ($arr as $key => $value) {
            $query = $query->GroupBy($key, $value);
        }
        return $query;
    }

    //在使用 Laravel 的关联查询中，我们经常使用 with 方法来避免 N+1 查询，但是 with 会将目标关联的所有字段全部查询出来，对于有强迫症的我们来说，当然是不允许的。 $topics = Topic::limit(2)->withCertain('user', ['username'])->get();

    public function scopeWithCertain($query, $relation, Array $columns)
    {
        return $query->with([$relation => function ($query) use ($columns) {
            $query->select($columns);
        }]);
    }


    public function scopeMultiSelect($query, $fileds = '')
    {
        if (!$fileds) {
            $fileds = '*';
        }
        if (is_array($fileds)) {
            $fileds = implode(',', $fileds);
        }
        return $query->select(DB::raw((string)$fileds));
    }

    /**
     * 根据条件获取用户信息
     * @param $where
     * @param string $fields
     * @return mixed
     */
    public function _getOne(array $where, $fields = "*")
    {
        return $this->multiSelect($fields)->multiWhere($where)->first();
    }

    /**
     * 按条件查询全部数据,根据配置显示条数显示
     */
    public function _getList(array $where = [], $fields = '*', array $order = [], $pageSize = 0)
    {
        if ($pageSize) {
            return $this->multiSelect($fields)->multiWhere($where)->multiOrder($order)->paginate($pageSize);
        } else {
            return $this->multiSelect($fields)->multiWhere($where)->multiOrder($order)->get();
        }
    }

    /**
     * 添加数据
     * @param $data
     */
    public function _add(array $data)
    {
        return $this->insertGetId($data);
    }

    /**
     * 修改数据
     * @param array $where
     * @param array $data
     * @return mixed
     */
    public function _updata(array $where, array $data)
    {
        return $this->multiWhere($where)->update($data);
    }

    /**
     * 删除数据
     * @param $where
     * @return mixed
     */
    public function _del(array $where)
    {
        return $this->multiWhere($where)->delete();
    }

    public function _count(array $where = [], $field = '*')
    {
        return $this->multiWhere($where)->count($field);
    }

    public function _sum(array $where = [], $field)
    {
        return $this->multiWhere($where)->sum($field);
    }

    public function _max(array $where = [], $field)
    {
        return $this->multiWhere($where)->max($field);
    }

    public function _min(array $where = [], $field)
    {
        return $this->multiWhere($where)->min($field);
    }

    public function _inc(array $where = [], $field, $num)
    {
        return $this->multiWhere($where)->increment($field, $num);
    }

    public function _dec(array $where = [], $field, $num)
    {
        return $this->multiWhere($where)->decrement($field, $num);
    }

    public function start()
    {
        DB::beginTransaction();
    }

    public function commit()
    {
        DB::commit();
    }

    public function rollBack()
    {
        DB::rollBack();
    }

    public function getPageList(array $where, $fields = '*', array $order = [], $pageSize = 10, $pageLength = 5)
    {
        $rows = $this->_getList($where, $fields, $order, $pageSize);
        if ($rows) {
            $rows = $rows->toArray();
            $rows['pageNoList'] = $this->getPageNoList($rows['last_page'], request('page', 1), $pageLength);
        }
        return $rows;
    }


    public function getPageNoList($totalPage, $pageNo, $pageSize)
    {
        $disPageList = $pageNo + $pageSize - 1;//最大链接显示数额赋值，公式为"当前页数 + 最大链接显示数额 -1"
        //前页面导航页数
        $pageNoList = [];
        //循环显示出当前页面导航页数
        if ($disPageList <= $totalPage) {
            for ($i = $pageNo; $i <= $disPageList; $i++) {
                $pageNoList[] = $i;
            }
            return $pageNoList;
        }
        if ($totalPage < $pageSize) {
            for ($i = 1; $i <= $totalPage; $i++) {
                $pageNoList[] = $i;
            }
            return $pageNoList;
        }
        $start = $totalPage - $pageSize + 1;
        for ($i = $start; $i <= $totalPage; $i++) {
            $pageNoList[] = $i;
        }
        return $pageNoList;
    }

    public function config()
    {
        $all = Config::all();
        foreach ($all as $k => $v) {
            $config[$v['key']] = $v['value'];
        }
        return $config;
    }
}